/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Mobilottery.Controls;

//
// Table like a matrix for choosing numbers
//
import java.util.Vector;
import javax.microedition.lcdui.*;

/**
 *
 * @version 2.0
 */
public class NumericTable extends CustomItem implements ItemCommandListener
{

    private final static Command CMD = new Command("Select", Command.ITEM, 0);
    private int rows = 5;
    private int cols = 5;
    private int dx = 20;
    private int dy = 20;
    private final static int UPPER = 0;
    private final static int IN = 1;
    private final static int LOWER = 2;
    private int location = IN;
    private int currentX = 0;
    private int currentY = 0;
    private boolean[][] data;
    private String errorMsg = null;
    //
    public int MaxSelection = 6;
    public int MaxNumber = 37;
    public int MarkedBgColor = 0xff0000c0;
    public int MarkedTextColor = 0xffffffc0;
    public int CurrentCellColor = 0xaaaaaac0;

    public NumericTable(String title, int p_rows, int p_cols, int p_dx, int p_dy)
    {
        super(title);
        rows = p_rows;
        cols = p_cols;
        dx = p_dx;
        dy = p_dy;
        data = new boolean[rows][cols];

        setDefaultCommand(CMD);
        setItemCommandListener(this);
    }

    protected int getMinContentHeight()
    {
        return (rows * dy) + 1;
    }

    protected int getMinContentWidth()
    {
        return (cols * dx) + 1;
    }

    protected int getPrefContentHeight(int width)
    {

        return getMinContentHeight();
    }

    protected int getPrefContentWidth(int height)
    {

        return getMinContentWidth();
    }

    protected void paint(Graphics g, int w, int h)
    {
        // draw horizontal lines
        for (int i = 0; i <= rows; i++)
        {
            g.drawLine(0, i * dy, cols * dx, i * dy);
        }

        // draw vertical lines
        for (int i = 0; i <= cols; i++)
        {
            g.drawLine(i * dx, 0, i * dx, rows * dy);
        }


        int oldColor = g.getColor();

        // current cell
        g.setColor(CurrentCellColor);
        g.fillRect((currentX * dx) + 1, (currentY * dy) + 1, dx - 1, dy - 1);

        // store clipping properties
        int oldClipX = g.getClipX();
        int oldClipY = g.getClipY();
        int oldClipWidth = g.getClipWidth();
        int oldClipHeight = g.getClipHeight();

        /*
        Font font = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_LARGE);
        g.setFont(font);
         */
        int clipX, clipY, clipW, clipH;
        int fh = g.getFont().getHeight();

        int markedCellPadding = 4;
        int num = 1;
        for (int i = 0; i < rows; i++)
        {
            for (int j = 0; j < cols; j++)
            {
                if (num <= MaxNumber)
                {
                    // set new clip area
                    clipX = (j * dx) + 1;
                    clipY = i * dy;
                    clipW = dx - 1;
                    clipH = dy;
                    g.setClip(clipX, clipY, clipW, clipH);

                    if (data[i][j] == false)
                    {
                        g.setColor(oldColor);
                    }
                    else
                    {
                        g.setColor(MarkedBgColor);
                        g.fillRect(clipX + markedCellPadding, clipY + markedCellPadding, clipW - 2 * markedCellPadding, clipH - 2 * markedCellPadding);

                        g.setColor(MarkedTextColor);
                    }
                    g.drawString(num + "", clipX + (clipW / 2), clipY + (clipH / 2) - (fh / 2), Graphics.HCENTER | Graphics.TOP);

                    num++;
                }
            }
        }

        if (errorMsg != null)
        {
            int stringWidth = g.getFont().stringWidth(errorMsg);

            // set new clip area (all control's space)
            clipX = 1;
            clipY = 1;
            clipW = cols * dx - 1;
            clipH = rows * dy - 1;
            g.setClip(clipX, clipY, clipW, clipH);

            int spaceX = 6;
            g.setColor(0xff4444);
            g.fillRoundRect(
                    clipX + clipW / 2 - stringWidth / 2 - spaceX,
                    clipY + (clipH / 2) - (fh / 2),
                    stringWidth + spaceX * 2,
                    fh,
                    spaceX, spaceX);

            g.setColor(0xffffff);
            g.drawString(errorMsg, clipX + 2 + clipW / 2, clipY + (clipH / 2) - (fh / 2), Graphics.HCENTER | Graphics.TOP);
        }

        // restore clipping properties
        g.setColor(oldColor);
        g.setClip(oldClipX, oldClipY, oldClipWidth, oldClipHeight);
    }

    protected boolean traverse(int dir, int viewportWidth, int viewportHeight, int[] visRect_inout)
    {
        if (errorMsg != null)
        {
            errorMsg = null;
            repaint();
            return true;
        }

        switch (dir)
        {
            case Canvas.DOWN:
                if (location == UPPER)
                {
                    location = IN;
                }
                else
                {
                    if (currentY < (rows - 1))
                    {
                        int newNum = currentX + (currentY + 1) * cols;
                        if (newNum < MaxNumber)
                        {
                            currentY++;
                            repaint(currentX * dx, (currentY - 1) * dy, dx, dy);
                            repaint(currentX * dx, currentY * dy, dx, dy);
                        }
                    }
                    else
                    {
                        location = LOWER;

                        return false;
                    }
                }
                break;

            case Canvas.UP:
                if (location == LOWER)
                {
                    location = IN;
                }
                else
                {
                    if (currentY > 0)
                    {
                        currentY--;
                        repaint(currentX * dx, (currentY + 1) * dy, dx, dy);
                        repaint(currentX * dx, currentY * dy, dx, dy);
                    }
                    else
                    {
                        location = UPPER;
                        return false;
                    }
                }
                break;

            case Canvas.LEFT:
                if (currentX > 0)
                {
                    currentX--;
                    repaint((currentX + 1) * dx, currentY * dy, dx, dy);
                    repaint(currentX * dx, currentY * dy, dx, dy);
                }
                break;

            case Canvas.RIGHT:
                if (currentX < (cols - 1))
                {
                    int newNum = currentX + 1 + (currentY * cols);
                    if (newNum < MaxNumber)
                    {
                        currentX++;
                        repaint((currentX - 1) * dx, currentY * dy, dx, dy);
                        repaint(currentX * dx, currentY * dy, dx, dy);
                    }
                }
                break;
        }

        visRect_inout[0] = currentX;
        visRect_inout[1] = currentY;
        visRect_inout[2] = dx;
        visRect_inout[3] = dy;

        return true;
    }

    public void commandAction(Command p_cmd, Item p_item)
    {
        if (errorMsg != null)
        {
            errorMsg = null;
            repaint();
            return;
        }


        if (data[currentY][currentX] == true)
        {
            // clear selection
            data[currentY][currentX] = false;
        }
        else
        {
            int totalSelected = 0;
            for (int i = 0; i < rows; i++)
            {
                for (int j = 0; j < cols; j++)
                {
                    if (data[i][j] == true)
                    {
                        totalSelected++;
                    }
                }
            }

            if (totalSelected < MaxSelection)
            {
                data[currentY][currentX] = true;
            }
            else
            {
                errorMsg = "Max allowed " + MaxSelection;
                repaint();
                return;
            }
        }
        repaint(currentX * dx, currentY * dy, dx, dy);
    }

    public int[] getSelectedNumbers()
    {
        int totalSelected = this.getSelectedNumbersAmount();

        int index = 0;
        int[] selectedItems = new int[totalSelected];
        for (int i = 0; i < rows; i++)
        {
            for (int j = 0; j < cols; j++)
            {
                if (data[i][j] == true)
                {
                	// get according to the number of passed rows double each each row for the col val + col offset j + 6 since we are counting from 1
                    selectedItems[index] = i * cols + j +1;  
                    index++;
                }
            }
        }

        return selectedItems;
    }

    public int getSelectedNumbersAmount()
    {
        int totalSelected = 0;
        for (int i = 0; i < rows; i++)
        {
            for (int j = 0; j < cols; j++)
            {
                if (data[i][j] == true)
                {
                    totalSelected++;
                }
            }
        }

        return totalSelected;
    }
}
